package jp.sourceforge.akjrcp.flvtools.explorer;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;

import jp.sourceforge.akjrcp.akj_betas.Akj_betasPlugin;
import jp.sourceforge.akjrcp.akj_betas.Messages;
import jp.sourceforge.akjrcp.flvtools.basic.FFMpegPage;
import jp.sourceforge.akjrcp.flvtools.basic.SimpleView.ConvertMonitorDone;
import jp.sourceforge.akjrcp.flvtools.basic.SimpleView.ConvertMonitorProcess;
import jp.sourceforge.akjrcp.flvtools.basic.SimpleView.ConvertMonitorStartSubTask;
import jp.sourceforge.akjrcp.flvtools.basic.SimpleView.EnableControl;
import jp.sourceforge.akjrcp.flvtools.basic.SimpleView.FinishAction;
import jp.sourceforge.akjrcp.util.FileNameUtils;
import jp.sourceforge.akjrcp.util.ProcessMonitor;

import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.jface.preference.IPreferenceStore;
import org.eclipse.ui.PlatformUI;

public class FFMpegExecuter extends Thread{
	private String extension;
	private File[] convertingFile;
	//IProgressMonitor convertMonitor;
	
	private FFMpegExecutable ffmpegExecutable;
	public FFMpegExecuter(FFMpegExecutable executable){
		this.ffmpegExecutable=executable;
		
	}
	public void debugArray(String[] array){
		String v="";
		for (int i = 0; i < array.length; i++) {
			v+="\""+array[i]+"\""+" ";
		}
		Akj_betasPlugin.getDefault().getProcessPrinter().printOutput(v+"\n");
	}
	
	public boolean isImageExport(String extension){
		return extension.equals("png") || extension.equals("jpg") || extension.equals("gif");
	}
	
	public void startExecute(){
		ffmpegExecutable.getProgressMonitor().beginTask(Messages.getString("converting"),convertingFile.length);
		this.start();
	}
	
	public void run(){
		for(int i=0;i<convertingFile.length;i++){
			ffmpegExecutable.executingFile(convertingFile[i],i);
			
			ExplorerView.log.info("converting:"+convertingFile[i]);
			PlatformUI.getWorkbench().getDisplay().syncExec(new ConvertMonitorStartSubTask(convertingFile[i].getName()));
		ProcessMonitor monitor=null;
		Runtime runtime=Runtime.getRuntime();
		ArrayList param=new ArrayList();
		IPreferenceStore store=Akj_betasPlugin.getDefault().getPreferenceStore();
		String ffmpegPath=store.getString(FFMpegPage.FFMPEG_PATH);
		param.add(ffmpegPath);
		param.add("-i");
		
		param.add(convertingFile[i].getAbsolutePath());
		
		if(isImageExport(extension)){
			param.add("-f");
			param.add("image2");
			param.add("-ss");
			param.add(store.getString(FFMpegPage.IMAGE_TIME));
			param.add("-vframes");
			param.add("1");
		}else{
		param.add("-b");
		param.add(""+store.getInt(FFMpegPage.VIDEO_BITRATE));
		param.add("-ab");
		param.add(""+store.getInt(FFMpegPage.AUDIO_BITRATE));
		param.add("-ar");
		param.add(""+store.getInt(FFMpegPage.EXPORT_WAVE_SAMPLERATE));
		param.add("-ac");
		param.add(""+store.getInt(FFMpegPage.EXPORT_WAVE_CHANNEL));
		
		param.add("-r");
		param.add(store.getString(FFMpegPage.VIDEO_FPS));
		
		String optionString=store.getString(FFMpegPage.FFMPEG_OPTION);
		
		if(extension.equals("avi")){
			param.add("-vcodec");
			param.add(store.getString(FFMpegPage.VIDEO_CODEC));
			param.add("-acodec");
			param.add("mp3");
		}else if(extension.equals("wmv")){
			param.add("-vcodec");
			param.add("wmv2");
			param.add("-acodec");
			param.add("mp3");
		}
		
		//Special trick CBR Encoding
		if(store.getString(FFMpegPage.MPEG_TYPE).equals(FFMpegPage.MPEG_TYPE_CBR)){
			param.add("-maxrate");
			param.add(""+store.getInt(FFMpegPage.VIDEO_BITRATE));
			param.add("-minrate");
			param.add(""+store.getInt(FFMpegPage.VIDEO_BITRATE));
			param.add("-bufsize");
			param.add("128");
		}
		
		String[] options=optionString.split(" ");//buggy
		for (int j = 0; j < options.length; j++) {
			param.add(options[j]);	
		}
		
		
		}
		
		param.add(FileNameUtils.getChangedExtensionName(convertingFile[i],extension));
		try {
			String arg[]=(String[])param.toArray(new String[0]);
			debugArray(arg);
			Process p=runtime.exec(arg);
			
			monitor=new ProcessMonitor(p,Akj_betasPlugin.getDefault().getProcessPrinter());
			monitor.startMonitor();
			
			
			try {
				p.waitFor();
			} catch (InterruptedException e) {
			
				e.printStackTrace();
			}
			
		} catch (IOException e) {
		
			e.printStackTrace();
		}
		
		monitor.stop();
		PlatformUI.getWorkbench().getDisplay().syncExec(new ConvertMonitorProcess());
		}
		
		ffmpegExecutable.executingFile(null,-1);//for finish
		
		PlatformUI.getWorkbench().getDisplay().syncExec(new ConvertMonitorDone());
		
		PlatformUI.getWorkbench().getDisplay().syncExec(new FinishAction());
		//finish
		//PlatformUI.getWorkbench().getDisplay().syncExec(new EnableControl(convertButton));
		
		
		
	}
	
	public class FinishAction extends Thread{
		public void run(){
			ffmpegExecutable.finishExecute();
		}
	}
	

	public File[] getFileList(){
		return convertingFile;
	}
	
	
	public class ConvertMonitorStartSubTask extends Thread{
		String name;
		public ConvertMonitorStartSubTask(String name){
			this.name=name;
		}
		public void run(){
			if(ffmpegExecutable.getProgressMonitor()!=null)
				ffmpegExecutable.getProgressMonitor().subTask(name);
		}
	}
	
	public class ConvertMonitorProcess extends Thread{
		
		public void run(){
			if(ffmpegExecutable.getProgressMonitor()!=null)
				ffmpegExecutable.getProgressMonitor().worked(1);
		}
	}
	
	public class ConvertMonitorDone extends Thread{
		public void run(){
			if(ffmpegExecutable.getProgressMonitor()!=null)
				ffmpegExecutable.getProgressMonitor().done();
		}
	}

	public FFMpegExecutable getFfmpegExecutable() {
		return ffmpegExecutable;
	}

	public void setFfmpegExecutable(FFMpegExecutable ffmpegExecutable) {
		this.ffmpegExecutable = ffmpegExecutable;
	}
	public String getExtension() {
		return extension;
	}
	public void setExtension(String extension) {
		this.extension = extension;
	}
	public File[] getConvertingFile() {
		return convertingFile;
	}
	public void setConvertingFile(File[] convertingFile) {
		this.convertingFile = convertingFile;
	}

}